﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms.Integration;
using System.Windows.Forms;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.GlobeCore;
using ESRI.ArcGIS.Analyst3D;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Animation;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.ArcGlobe;
using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.ArcScene;
using ESRI.ArcGIS.CatalogUI;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.SystemUI;



namespace VCampusV10
{
    public partial class MainForm : DevComponents.DotNetBar.Office2007RibbonForm
    {
        private string _MyAppRoot=System.Windows.Forms.Application.StartupPath + @"\..\..\";
        //private string _FlyPathRoot = System.Windows.Forms.Application.StartupPath + "\\animate\\";
        private string _OperateType = string.Empty;
        public MainForm()
        {
            string defaultPath = _MyAppRoot + @"GlobeData\Campus3D.3dd";
            string campus3dpath = @"E:\3S综合实习\GlobeData\Campus3D.3dd";
            ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);
            InitializeComponent();
            Open3dFile(defaultPath);

            
        }
        private void MainForm_Load(object sender, EventArgs e)
        {
            //添加鼠标滚动事件
            this.MouseWheel += new System.Windows.Forms.MouseEventHandler(axGlobeControl1_OnMouseWheel);
            
        }
        private void OpenSceneBtn_Click(object sender, EventArgs e)
        {
            OpenSceneDialog();
        }
        private void OpenSeceneTopBtn_Click(object sender, EventArgs e)
        {
            OpenSceneDialog();
        }
        private void PauseFlyItem_Click(object sender, EventArgs e)
        {
            pauseAnimation(axGlobeControl1.Globe);
        }

        private void StopFlyItem_Click(object sender, EventArgs e)
        {
            stopAnimation(axGlobeControl1.Globe);
        }

        private void EntireSchoolItem_Click(object sender, EventArgs e)
        {
            string flyFilePath = _MyAppRoot + @"GlobeData\animate\FlyToBuilding2.aga";
            playAnimation(flyFilePath, axGlobeControl1.Globe);
        }
       
        private void Open3dFile(string FullFileName)
        {
            if (axGlobeControl1.Check3dFile(FullFileName))
            {
                this.axGlobeControl1.Load3dFile(FullFileName);
                this.axGlobeControl1.Refresh();
            }
            else
            {
                MessageBox.Show("您想打开的文件不是正确的三维格式数据");
            }
                      
        }

        
        private void SetMyIcon(string IconName)
        {
            this.axGlobeControl1.MouseIcon = new Icon(_MyAppRoot + @"Images\"+IconName);
            this.axGlobeControl1.MousePointer = esriControlsMousePointer.esriPointerCustom;
        }    
        #region 允许鼠标滚动操作
        private void axGlobeControl1_OnMouseWheel(object sender, MouseEventArgs e)
        {
            try
            {               
                System.Drawing.Point pSceLoc = axGlobeControl1.PointToScreen(axGlobeControl1.Location);
                System.Drawing.Point Pt = this.PointToScreen(e.Location);
                if (Pt.X < pSceLoc.X || Pt.X > pSceLoc.X + axGlobeControl1.Width || Pt.Y < pSceLoc.Y || Pt.Y > pSceLoc.Y + axGlobeControl1.Height)
                {
                    return;
                }
                double scale = 0.3;
                if (e.Delta < 0) scale = -scale;
                IGlobeCamera pGlobeCamera = axGlobeControl1.GlobeCamera;
                ICamera pCamera = pGlobeCamera as ICamera;
                IGlobeDisplay pGlobeDisplay = axGlobeControl1.GlobeDisplay;
                if (pGlobeCamera.OrientationMode == esriGlobeCameraOrientationMode.esriGlobeCameraOrientationGlobal)
                {
                    double zt, xo, yo, zo;
                    pGlobeCamera.GetObserverLatLonAlt(out xo, out yo, out zo);
                    pGlobeDisplay.GetSurfaceElevation(xo, yo, true, out zt);
                    IPoint pObserver = new PointClass();
                    pObserver.PutCoords(xo, yo);
                    double zt1 = zt * (UnitSacleToMeter(axGlobeControl1.Globe.GlobeUnits));
                    zo = (zo - zt1) * (1 + scale);
                    pGlobeCamera.SetObserverLatLonAlt(xo, yo, zo);
                }
                else
                {
                    pCamera.ViewingDistance += pCamera.ViewingDistance * scale;
                }
                axGlobeControl1.GlobeDisplay.RefreshViewers();
            }
            catch
            {
            }
        }
        private static double UnitSacleToMeter(esriUnits unit)
        {
            switch (unit)
            {
                case esriUnits.esriKilometers:
                    return 1000;
                case esriUnits.esriMeters:
                    return 1;
                default:
                    return -1;
            }
        }
        #endregion
        private void OpenSceneDialog()
        {
            OpenFileDialog openSceneFileDialog = new OpenFileDialog();
            openSceneFileDialog.InitialDirectory = System.Windows.Forms.Application.StartupPath + @"\data\chap8";
            openSceneFileDialog.Filter = "3dd数据(*.3dd)|*.3dd";
            openSceneFileDialog.RestoreDirectory = true;
            if (openSceneFileDialog.ShowDialog() == DialogResult.OK)
            {
                string SceneFilePath = openSceneFileDialog.FileName.Substring(0, openSceneFileDialog.FileName.Length - openSceneFileDialog.SafeFileName.Length);
                string SceneFileName = openSceneFileDialog.SafeFileName;

                Open3dFile(SceneFilePath+SceneFileName);                
            }         
        }
        private void FlyTo(double x,double y,double h)
        {
            IGlobeCamera pGlobeCamera = GetGlobeCamera(); 
            //pGlobeCamera.SetTargetLatLonAlt(x, y, h);
           
            pGlobeCamera.OrientationMode = esriGlobeCameraOrientationMode.esriGlobeCameraOrientationGlobal;
            pGlobeCamera.SetObserverLatLonAlt(x, y, h);
            
            axGlobeControl1.GlobeDisplay.RefreshViewers();
        }
        private IGlobeCamera GetGlobeCamera()
        {
            ICamera pCamera = axGlobeControl1.Globe.GlobeDisplay.ActiveViewer.Camera;
            return (IGlobeCamera)pCamera;
        }
        private void FlyToCampus()
        {
            IEnvelope env = new EnvelopeClass();
            env.PutCoords(116.19758647181, 26.0223326126646, 116.213941296692, 26.0459062076152);
            IGlobeCamera pGlobeCamera = GetGlobeCamera();
            ISceneViewer sceneViewer = axGlobeControl1.Globe.GlobeDisplay.ActiveViewer;
            pGlobeCamera.SetToZoomToExtents(env, axGlobeControl1.Globe, sceneViewer);
        }       

        
        private void playAnimation(string FlyFilePath, IGlobe globe)
        {
            IGlobeDisplay globeDisplay;
            globeDisplay = globe.GlobeDisplay;
            Scene scene = (Scene)globeDisplay.Scene;
            IBasicScene2 basicScene = (IBasicScene2)scene;
            IAGAnimationUtils animUtils = new AGAnimationUtilsClass();            
            IAGAnimationPlayer animPlayer = new AGAnimationUtilsClass();
            IAnimationExtension animExt = basicScene.AnimationExtension;
            IAGAnimationTracks pTracks = animExt.AnimationTracks;
            animUtils.LoadAnimationFile(pTracks.AnimationObjectContainer,FlyFilePath);            
            animPlayer = (IAGAnimationPlayer)animUtils;

            //pEnv          
            IAGAnimationEnvironment pEnv = animExt.AnimationEnvironment;
            pEnv.PlayMode = esriAnimationPlayMode.esriAnimationPlayOnceForward;
            animPlayer.PlayAnimation(pTracks, pEnv, null);
        }

        private void stopAnimation(IGlobe globe)
        {
            IGlobeDisplay globeDisplay = globe.GlobeDisplay;
            Scene scene = (Scene)globeDisplay.Scene;
            IBasicScene2 basicScene = (IBasicScene2)scene;

            IAGAnimationUtils animUtils = new AGAnimationUtilsClass();
            IAGAnimationPlayer animPlayer = new AGAnimationUtilsClass();
            IAnimationExtension animExt = basicScene.AnimationExtension;
            IAGAnimationTracks pTracks = animExt.AnimationTracks;
            IAGAnimationEnvironment pEnv = animExt.AnimationEnvironment;

            animUtils = new AGAnimationUtilsClass();

            animPlayer = (IAGAnimationPlayer)animUtils;
            animPlayer.StopAnimation();
        }

        private void pauseAnimation(IGlobe globe)
        {
            IGlobeDisplay globeDisplay = globe.GlobeDisplay;
            Scene scene = (Scene)globeDisplay.Scene;
            IBasicScene2 basicScene = (IBasicScene2)scene;

            IAGAnimationUtils animUtils = new AGAnimationUtilsClass();
            IAGAnimationPlayer animPlayer = new AGAnimationUtilsClass();
            IAnimationExtension animExt = basicScene.AnimationExtension;
            IAGAnimationTracks pTracks = animExt.AnimationTracks;
            IAGAnimationEnvironment pEnv = animExt.AnimationEnvironment;

            animUtils = new AGAnimationUtilsClass();
            animPlayer = (IAGAnimationPlayer)animUtils;          

            animPlayer.PauseAnimation();
        }

        private void clearAnimation(IGlobe globe)
        {
            IGlobeDisplay globeDisplay = globe.GlobeDisplay;
            Scene scene = (Scene)globeDisplay.Scene;
            IBasicScene2 basicScene = (IBasicScene2)scene;

            IAnimationExtension animExt = basicScene.AnimationExtension;
            IAGAnimationTracks pTracks = animExt.AnimationTracks;
            pTracks.RemoveAllTracks();
            globeDisplay.RefreshViewers();
        }

        private void StartFlyItem_Click(object sender, EventArgs e)
        {
            string flyFilePath = _MyAppRoot + @"GlobeData\animate\FlyToBuilding.aga";
            playAnimation(flyFilePath, axGlobeControl1.Globe);
        }                     

        private void SelFeatureBtn_Click(object sender, EventArgs e)
        {
            ICommand command = new ControlsGlobeSelectFeaturesToolClass();
            command.OnCreate(axGlobeControl1.Object);
            if (command.Enabled == true)
            {
                axGlobeControl1.CurrentTool = (ITool)command;
                _OperateType = "SELECT";
            }
            else
            {
                MessageBox.Show("current tool is not enable");
            }
        }
        private void ClearSelBtn_Click(object sender, EventArgs e)
        {
            axGlobeControl1.GlobeDisplay.Scene.ClearSelection();
            axGlobeControl1.Refresh();
        }
        private void axGlobeControl1_OnMouseUp(object sender, IGlobeControlEvents_OnMouseUpEvent e)
        {
            if (_OperateType.Equals("SELECT"))
            {
                //MessageBox.Show("");
                ICursor pCursor;
                IFeature pFeature;
                ILayer modelLayer = getFloatLayerByName("教学楼模型");
                IFeatureSelection pFeatureSelection = modelLayer as IFeatureSelection;
                ISelectionSet pSelectionSet = pFeatureSelection.SelectionSet;
                pSelectionSet.Search(null, true, out pCursor);
                IFeatureCursor pFeatureCursor = (IFeatureCursor)pCursor; ;
                pFeature = pFeatureCursor.NextFeature();
                //MessageBox.Show(pFeature.get_Value(0).ToString());
                string name = pFeature.get_Value(3).ToString();
                int levle=Int32.Parse(pFeature.get_Value(4).ToString());
                double lng = Double.Parse(pFeature.get_Value(5).ToString());
                double lat = Double.Parse(pFeature.get_Value(6).ToString());
                InfoWindows.ShowBuildingInfo SBI = new InfoWindows.ShowBuildingInfo(
                    new Entity.BuildingInfo(name,levle,lng,lat));
                System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(SBI);
                SBI.ShowDialog();
                SetPan();
            }
            else if (_OperateType.Equals("SEL_ROAD"))
            {
                ICursor pCursor;
                IFeature pFeature;
                ILayer RoadLayer = getFloatLayerByName("道路网");
                IFeatureSelection pFeatureSelection = RoadLayer as IFeatureSelection;
                ISelectionSet pSelectionSet = pFeatureSelection.SelectionSet;
                pSelectionSet.Search(null, true, out pCursor);
                IFeatureCursor pFeatureCursor = (IFeatureCursor)pCursor; ;
                pFeature = pFeatureCursor.NextFeature();
                if (pFeature != null)
                {
                    string name = pFeature.get_Value(4).ToString();
                    int roadLevel = Int32.Parse(pFeature.get_Value(5).ToString());
                    double roadLength = Double.Parse(pFeature.get_Value(7).ToString());
                    RoadInfoWindow riw = new RoadInfoWindow(new Entity.RoadInfo(name, roadLevel, roadLength));
                    riw.ShowDialog();
                }
                else
                {
                    MessageBox.Show("您没有选择任何对象");
                }
                
            }
        }

        private ILayer getFloatLayerByName(string name)
        {            
            IEnumLayer floatingLayers = axGlobeControl1.Globe.get_GlobeLayers(null, false, false, true);
            ILayer ModelLayer;
            ModelLayer = floatingLayers.Next();
            //最好判断下图层的名称是否和指定的名称相同
            while (ModelLayer != null)
            {
                if (ModelLayer.Name.Equals(name))
                {
                    break;
                }
                ModelLayer = floatingLayers.Next();
            }
            return ModelLayer;
        }
        private ILayer getLayerByName(string name)
        {
            IEnumLayer floatingLayers = axGlobeControl1.Globe.get_GlobeLayers(null, false, false, true);
            ILayer ModelLayer;
            ModelLayer = floatingLayers.Next();
            //最好判断下图层的名称是否和指定的名称相同
            while (ModelLayer != null)
            {
                if (ModelLayer.Name.Equals(name))
                {
                    break;
                }
                ModelLayer = floatingLayers.Next();
            }
            return ModelLayer;
        }
        private void SetPan()
        {
            ICommand command = new ControlsGlobePanDragToolClass();
            command.OnCreate(axGlobeControl1.Object);
            if (command.Enabled == true)
            {
                axGlobeControl1.CurrentTool = (ITool)command;
                _OperateType = "PAN";
            }
            else
            {
                MessageBox.Show("current tool is not enable");
            }
        }

        private void SetTool(string OperateType,ICommand command)
        {
            //ICommand command = new ControlsGlobePanDragToolClass();
            command.OnCreate(axGlobeControl1.Object);
            if (command.Enabled == true)
            {
                axGlobeControl1.CurrentTool = (ITool)command;
                _OperateType = OperateType;
            }
            else
            {
                MessageBox.Show("current tool is not enable");
            }
        }       
       
        private void PanBtn_Click(object sender, EventArgs e)
        {
            SetPan();
        }

        private void FlyBtn_Click(object sender, EventArgs e)
        {
            SetTool("FLY", new ControlsGlobeFlyToolClass());
        }

        private void navigationBtn_Click(object sender, EventArgs e)
        {
            SetTool("NAVIGATE",new ControlsGlobeNavigateToolClass());
        }

        private void EntireBtn_Click(object sender, EventArgs e)
        {
            SetTool("ENTIRE", new ControlsFullScreenCommandClass());
        }

        private void buttonItem1_Click_1(object sender, EventArgs e)
        {
            SetTool("ZOOMINOUT",new ControlsGlobeZoomInOutToolClass());
        }

        private void AroundBtn_Click(object sender, EventArgs e)
        {
            SetTool("AROUNE", new ControlsGlobeLookAroundToolClass());
        }
        private void FindRoadInfoBtn_Click(object sender, EventArgs e)
        {
            ILayer RoadLayer = getFloatLayerByName("道路网");
            //MessageBox.Show(RoadLayer.Name);
            IFeatureSelection pFeatureSlection;
            IQueryFilter pQueryFilter;            

            pQueryFilter = new QueryFilterClass();
            //strName = textBox1.Text;
            InputRoadName irn = new InputRoadName();
            irn.ShowDialog();
            if (irn.DialogResult == DialogResult.OK)
            {
                string roadName = irn.RoadName;
                pQueryFilter.WhereClause = "name='" + roadName + "'";
                IFeatureLayer pFeatureLayer = RoadLayer as IFeatureLayer;
                pFeatureSlection = (IFeatureSelection)pFeatureLayer;
                pFeatureSlection.SelectFeatures(pQueryFilter, esriSelectionResultEnum.esriSelectionResultNew, false);
                axGlobeControl1.Refresh();                
            }
            
        }

        private void RoadInfoBtn_Click(object sender, EventArgs e)
        {            
            SetTool("SEL_ROAD",new ControlsGlobeSelectFeaturesToolClass());
        }
       
        private void buttonItem1_Click(object sender, EventArgs e)
        {
            //test 1
            //InfoWindows.ShowBuildingInfo win = new InfoWindows.ShowBuildingInfo();
            //System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(win);
            ////win.Show();
            //win.ShowDialog();

            //test2
            //IEnumLayer baseMap;
            IGlobe pGlobe = axGlobeControl1.Globe;
            //baseMap = pGlobe.get_GlobeLayers(null,true,true,true);
            IEnumLayer floatingLayers = pGlobe.get_GlobeLayers(null, false, false, true);
            ILayer ModelLayer;
            ModelLayer = floatingLayers.Next();
            IFeatureLayer pFeatureLayer = ModelLayer as IFeatureLayer;
            IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
            IQueryFilter pQueryFilter = new QueryFilterClass();
            pQueryFilter.WhereClause = "FID=0";
            IFeatureCursor pUpdateCursor = pFeatureClass.Update(pQueryFilter, false);
            IFeature pFeature = (IFeature)(pUpdateCursor.NextFeature());
            string value = pFeature.get_Value(0).ToString() + "   " + pFeature.get_Value(1).ToString();
        }

        private void ClearSelBtn_Click_1(object sender, EventArgs e)
        {
            axGlobeControl1.GlobeDisplay.Scene.ClearSelection();
        }

      
        
    }
}
